package com.umeox.quranplayer.ui

import android.annotation.SuppressLint
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.text.TextUtils
import android.text.format.DateUtils
import android.util.Log
import android.view.View
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.SeekBar
import android.widget.TextView
import androidx.constraintlayout.widget.Group
import androidx.lifecycle.lifecycleScope
import com.umeox.moto.common.log.Logger
import com.umeox.moto.common.utils.DateUtils.formatTime
import com.umeox.moto.watch.themes.app.ThemeAppCompatActivity
import com.umeox.quranplayer.R
import com.umeox.quranplayer.repository.*
import com.umeox.quranplayer.repository.model.QuranAudioBean
import com.yc.music.config.MusicConstant
import com.yc.music.inter.OnPlayerEventListener
import com.yc.music.model.AudioBean
import com.yc.music.service.PlayService
import com.yc.music.tool.BaseAppHelper
import com.yc.music.utils.MusicSpUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.lang.StringBuilder
import java.util.*
import kotlin.math.abs

class MainActivity : ThemeAppCompatActivity(), View.OnClickListener, OnPlayerEventListener {
    /**
     * 播放模式
     */
    private var playModeLevel = 0

    /**
     * 播放位置(秒)
     */
    private var playPosition = 0

    /**
     * 播放音频所在列表
     */
    private var playListType = 0

    /**
     * 播放音频名称
     */
    private var playName = ""

    /**
     * 初次启动
     */
    private var first = true

    private var tvTitleAr: TextView? = null
    private var tvTitleEn: TextView? = null
    private var tvCurrentTime: TextView? = null
    private lateinit var sbProgress: SeekBar
    private var tvTotalTime: TextView? = null
    private var titleGroup: Group? = null
    private var ivMorning: ImageView? = null
    private var ivPrev: ImageView? = null
    private var ivPlay: ImageView? = null
    private var ivNext: ImageView? = null
    private var ivVolume: ImageView? = null
    private var ivPlayMode: ImageView? = null
    private var ivMusicList: ImageView? = null
    private var pbLoadFile: ProgressBar? = null

    private var audioBean: QuranAudioBean? = null

    private lateinit var mPlayServiceConnection: PlayServiceConnection

    private var mLastProgress = 0

    private var isDraggingProgress = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        startCheckService(window.decorView)
        playModeLevel =
            MusicSpUtils.getInstance(MusicConstant.SP_NAME).getInt(MusicConstant.PLAY_MODE, 0)

        playPosition =
            MusicSpUtils.getInstance(MusicConstant.SP_NAME).getInt(MusicConstant.PLAY_POSITION, 0)

        if (playPosition < 1000) {
            playPosition = 0
        }
        playName = MusicSpUtils.getInstance(MusicConstant.SP_NAME).getString(SP_KEY_MUSIC_NAME, "")

        playListType = MusicSpUtils.getInstance(MusicConstant.SP_NAME)
            .getInt(INTENT_KEY_LIST_TYPE, LIST_TYPE_QURAN)
        Logger.e("playName=$playName,playPosition=$playPosition")

        initView()
        initPlayServiceListener()
        buildLocalAudioListData()
        initListener()
    }

    private fun initView() {
        tvTitleAr = findViewById(R.id.tv_title_ar)
        tvTitleEn = findViewById(R.id.tv_title_en)
        tvCurrentTime = findViewById(R.id.tv_current_time)
        sbProgress = findViewById(R.id.sb_progress)
        tvTotalTime = findViewById(R.id.tv_total_time)
        titleGroup = findViewById(R.id.group_titles)

        ivMorning = findViewById(R.id.iv_morning)
        ivPrev = findViewById(R.id.iv_prev)
        ivPlay = findViewById(R.id.iv_play)
        ivNext = findViewById(R.id.iv_next)
        ivVolume = findViewById(R.id.iv_volume)
        ivPlayMode = findViewById(R.id.iv_play_mode)
        ivMusicList = findViewById(R.id.iv_music_list)
        pbLoadFile = findViewById(R.id.pb_load_file)
        ivPlayMode?.setImageLevel(playModeLevel)

        setViewEnable(false)
    }

    private fun setViewEnable(enable: Boolean) {
        ivPlay?.isClickable = enable
        ivPrev?.isClickable = enable
        ivNext?.isClickable = enable
        sbProgress.isEnabled = enable
    }

    private fun initListener() {
        ivPlay?.setOnClickListener(this)
        ivPrev?.setOnClickListener(this)
        ivNext?.setOnClickListener(this)
        ivVolume?.setOnClickListener(this)
        ivPlayMode?.setOnClickListener(this)
        ivMusicList?.setOnClickListener(this)

        val onSeekBarChangeListener: SeekBar.OnSeekBarChangeListener =
            object : SeekBar.OnSeekBarChangeListener {
                override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
                    if (seekBar === sbProgress) {
                        if (abs(progress - mLastProgress) >= DateUtils.SECOND_IN_MILLIS) {
                            MusicSpUtils.getInstance(MusicConstant.SP_NAME)
                                .put(MusicConstant.PLAY_POSITION, progress)
                            tvCurrentTime!!.text = formatTime(progress.toLong())
                            mLastProgress = progress
                        }
                    }
                }

                override fun onStartTrackingTouch(seekBar: SeekBar) {
                    if (seekBar === sbProgress) {
                        isDraggingProgress = true
                    }
                }

                /**
                 * 通知用户已结束触摸手势,触摸结束时调用
                 * @param seekBar               seekBar
                 */
                override fun onStopTrackingTouch(seekBar: SeekBar) {
                    if (seekBar === sbProgress) {
                        isDraggingProgress = false

                        val musicService = BaseAppHelper.get().musicService
                        if (musicService != null && musicService.isPlaying || musicService.isPausing) {
                            val progress = seekBar.progress
                            musicService.seekTo(progress)
                        } else {
                            seekBar.progress = 0
                        }
                    }
                }
            }
        sbProgress.setOnSeekBarChangeListener(onSeekBarChangeListener)
    }

    @SuppressLint("SetTextI18n")
    private fun setViewData(playingMusic: QuranAudioBean) {
        when (playingMusic.title) {
            MORNING_QURAN_FILE_NAME -> {
                titleGroup?.visibility = View.INVISIBLE
                ivMorning?.visibility = View.VISIBLE
                ivMorning?.setImageResource(R.drawable.ic_morning)
            }

            NIGHT_QURAN_FILE_NAME -> {
                titleGroup?.visibility = View.INVISIBLE
                ivMorning?.visibility = View.VISIBLE
                ivMorning?.setImageResource(R.drawable.ic_night)
            }

            else -> {
                titleGroup?.visibility = View.VISIBLE
                ivMorning?.visibility = View.INVISIBLE
                tvTitleAr!!.text = playingMusic.nameAR
                tvTitleEn!!.text = playingMusic.nameEN
            }
        }

        tvCurrentTime!!.text = formatTime(playPosition.toLong())
        sbProgress.max = playingMusic.duration.toInt()
        sbProgress.progress = playPosition
        sbProgress.secondaryProgress = 0

        tvTotalTime!!.text = formatTime(playingMusic.duration)
    }

    private fun initPlayServiceListener() {
        if (BaseAppHelper.get().musicService == null) {
            return
        }
        BaseAppHelper.get().musicService.addOnPlayEventListener(this)
        val musicService = BaseAppHelper.get().musicService
        val playing = musicService.isPlaying
        ivPlay!!.isSelected = playing || musicService.isPreparing
    }


    override fun onDestroy() {
        super.onDestroy()
        if (::mPlayServiceConnection.isInitialized) {
            BaseAppHelper.get().musicService?.removeOnPlayEventListener(this)
        }
    }

    private fun onChangeImpl(music: QuranAudioBean?) {
        MusicSpUtils.getInstance(MusicConstant.SP_NAME).put(SP_KEY_MUSIC_NAME, music?.title ?: "")

        if (music == null) {
            return
        }

        when (music.title) {
            MORNING_QURAN_FILE_NAME -> {
                titleGroup?.visibility = View.INVISIBLE
                ivMorning?.visibility = View.VISIBLE
                ivMorning?.setImageResource(R.drawable.ic_morning)
            }

            NIGHT_QURAN_FILE_NAME -> {
                titleGroup?.visibility = View.INVISIBLE
                ivMorning?.visibility = View.VISIBLE
                ivMorning?.setImageResource(R.drawable.ic_night)
            }

            else -> {
                titleGroup?.visibility = View.VISIBLE
                ivMorning?.visibility = View.INVISIBLE
                tvTitleAr!!.text = music.nameAR
                tvTitleEn!!.text = music.nameEN
            }
        }

        tvCurrentTime!!.text = formatTime(playPosition.toLong())
        sbProgress.max = music.duration.toInt()
        sbProgress.progress = 0
        tvTotalTime!!.text = formatTime(music.duration)

        ivPlay!!.isSelected =
            BaseAppHelper.get().musicService.isPlaying || BaseAppHelper.get().musicService.isPreparing
    }

    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.iv_play -> {
                BaseAppHelper.get().musicService?.playPause()
            }

            R.id.iv_next -> BaseAppHelper.get().musicService?.doNext()
            R.id.iv_prev -> BaseAppHelper.get().musicService?.doPrev()
            R.id.iv_volume -> {
                startActivity(Intent(this, VolumeSettingActivity::class.java))
            }

            R.id.iv_music_list -> {
                startActivityForResult(
                    Intent(this, MusicGroupActivity::class.java),
                    QURAN_LIST_REQUEST_CODE
                )
            }

            R.id.iv_play_mode -> {
                playModeLevel += 2
                if (playModeLevel > 2) {
                    playModeLevel = 0
                }
                MusicSpUtils.getInstance(MusicConstant.SP_NAME)
                    .put(MusicConstant.PLAY_MODE, playModeLevel)
                ivPlayMode?.setImageLevel(playModeLevel)
            }

            else -> {}
        }
    }

    override fun onChange(music: AudioBean?) {
        if (music is QuranAudioBean) {
            onChangeImpl(music)
        }
    }

    override fun onPlayerStart() {
        ivPlay!!.isSelected = true
//        if (first) {
//            BaseAppHelper.get().musicService.playPause()
//        }
    }

    override fun onPlayerPause() {
        ivPlay!!.isSelected = false
//        if (first) {
//            first = false
//            BaseAppHelper.get().musicService.seekTo(playPosition)
//        }
    }

    override fun onCompletion() {
    }

    override fun onUpdateProgress(progress: Int) {
        val progressCompat = if (progress < 1000) {
            0
        } else {
            progress
        }
        sbProgress!!.progress = progressCompat
    }

    override fun onBufferingUpdate(percent: Int) {
    }

    override fun onTimer(remain: Long) {
    }

    override fun onDuration(totalDuration: Int) {

    }

    /**
     * 检测服务
     */
    private fun startCheckService(rootView: View) {
        if (BaseAppHelper.get().playService == null) {
            startService()
            rootView.postDelayed({ bindService() }, 500)
        }
    }

    /**
     * 开启服务
     */
    private fun startService() {
        val intent = Intent(this, PlayService::class.java)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(intent)
        } else {
            startService(intent)
        }
    }

    /**
     * 绑定服务
     * 注意对于绑定服务一定要解绑
     */
    private fun bindService() {
        val intent = Intent()
        intent.setClass(mContext, PlayService::class.java)
        mPlayServiceConnection = PlayServiceConnection()
        mContext.bindService(intent, mPlayServiceConnection, Context.BIND_AUTO_CREATE)
    }

    /**
     * 构建数据集合
     */
    private fun buildLocalAudioListData() {
        pbLoadFile?.visibility = View.VISIBLE
        lifecycleScope.launchWhenCreated {
            QuranAudioManager.buildMusicList()

            withContext(Dispatchers.Main) {
                if (TextUtils.isEmpty(playName)) {
                    playName = DEFAULT_QURAN_TITLE
                    playPosition = 0
                }

                for (bean in updateMusicList()) {
                    if (bean.title.trim() == playName) {
                        audioBean = bean
                        pbLoadFile?.visibility = View.GONE
                        setViewData(bean)
                    }
                }

                val helper = BaseAppHelper.get()
                if (audioBean == null) {
                    audioBean = helper.musicList[0] as QuranAudioBean
                    pbLoadFile?.visibility = View.GONE
                    setViewData(audioBean!!)
                }

                setViewEnable(true)

                //helper.playService.play(helper.musicList.indexOf(audioBean))
            }
        }
    }

    private fun updateMusicList(): MutableList<QuranAudioBean> {
        //初始化当前列表
        var list = when (playListType) {
            LIST_TYPE_QURAN -> QuranAudioManager.quranList
            LIST_TYPE_FAVORITE -> QuranAudioManager.favoriteList
            LIST_TYPE_MORNING -> QuranAudioManager.morningList
            LIST_TYPE_NIGHT -> QuranAudioManager.nightList
            else -> QuranAudioManager.quranList
        }
        if (list.isEmpty()) {
            list = QuranAudioManager.quranList
            playListType = LIST_TYPE_QURAN
        }

        val musicList = BaseAppHelper.get().musicList
        musicList.clear()
        musicList.addAll(list)
        return list
    }

    private fun formatTime(milliseconds: Long): String {
        val stringBuilder = StringBuilder()
        val mFormatter = Formatter(stringBuilder, Locale.getDefault())
        if (milliseconds <= 0 || milliseconds >= 24 * 60 * 60 * 1000) {
            return mFormatter.format(Locale.getDefault(), "%02d:%02d", 0, 0).toString()
        }
        val totalSeconds = milliseconds / 1000
        val seconds = totalSeconds % 60
        val minutes = totalSeconds / 60
        val hours = totalSeconds / 3600


        return if (hours > 0) {
            mFormatter.format(Locale.getDefault(), "%03d:%02d", minutes, seconds).toString()
        } else {
            mFormatter.format(Locale.getDefault(), "%03d:%02d", minutes, seconds).toString()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == QURAN_LIST_REQUEST_CODE) {
            data?.let {
                playListType = it.getIntExtra(INTENT_KEY_LIST_TYPE, LIST_TYPE_QURAN)
                playName = it.getStringExtra(INTENT_KEY_AUDIO_NAME) ?: DEFAULT_QURAN_TITLE

                for (bean in updateMusicList()) {
                    if (bean.title.trim() == playName) {
                        audioBean = bean
                        setViewData(bean)
                    }
                }
                MusicSpUtils.getInstance(MusicConstant.SP_NAME)
                    .put(INTENT_KEY_LIST_TYPE, playListType)
                val helper = BaseAppHelper.get()
                helper.playService.play(helper.musicList.indexOf(audioBean))
            }
        }
    }

    inner class PlayServiceConnection : ServiceConnection {
        override fun onServiceConnected(name: ComponentName, service: IBinder) {
            BaseAppHelper.get().playService = (service as PlayService.PlayBinder).service
            lifecycleScope.launch(Dispatchers.Main) {
                initPlayServiceListener()
            }
        }

        override fun onServiceDisconnected(name: ComponentName) {

        }
    }
}